package cn.com.surker.workcon.service.fengdu;

import cn.com.surker.base.system.dao.SysStorageLogDao;
import cn.com.surker.base.system.entity.SysLine;
import cn.com.surker.base.system.entity.SysStorageLog;
import cn.com.surker.control.entity.ControlExpend;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.external.dao.LabExpendBDao;
import cn.com.surker.external.entity.LabExpendB;
import cn.com.surker.lab.entity.LabExpend;
import cn.com.surker.lab.entity.LabExpendOther;
import cn.com.surker.lab.vo.LabExpendVoB;
import cn.com.surker.production.dao.ProductionInvoiceDao;
import cn.com.surker.production.entity.vo.ProductionInvoiceVo;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.StringUtils;
import cn.com.surker.workcon.common.GKJDBCService;
import cn.com.surker.workcon.service.DosageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 中联工消耗信息 Mapper 接口
 * </p>
 *
 * @author admin
 * @since 2024-09-26
 */
public class DosageServiceImpl extends GKJDBCService implements DosageService {

	@Autowired
	private JdbcTemplate mysqlJdbcTemplate;

	@Resource
	private ProductionInvoiceDao invoiceDao;

	@Value("${erp.datasource.erp.db}")
	private String erpDb;

	//	b库消耗
	@Resource
	protected LabExpendBDao labExpendBDao;

	@Resource
	private SysStorageLogDao sysStorageLogDao;

	/**
	 * 根据盘id,查询工控机消耗信息,丰都返回的是现场的b库数据,要根据b库数据将反推真实数据,同时将b库数据写入b库
	 *
	 * @param pieId
	 * @param batchStere
	 * @return
	 */
	public List<LabExpend> findByPieId(Long lineId, Long invoiceId, Long batchId, String prodId, String pieId, Date batTime,
									   Double batchStere, Long formulaId, Double formulaWater, Long levelOptimizeId, Date createDate) {
		if (lineId == null || StringUtils.isBlank(pieId)) {
			return null;
		}
		SysLine line = getLine(lineId);
		if (line == null) {
			return null;
		}
		JdbcTemplate lineJdbcTemp = getLineJdbcTemp(line);
		//	查询sql
		String querySql = "SELECT  ID,HTID,TrayNum,StuffID,StuffName,SiloID\n" +
			"      ,SiloName,TargetNum,FormulaNum,StuffUsedNum,QueryNum,FallNum,WaterRate,SandRate,CheckNum\n" +
			"  FROM HistoryItems where HTID = '" + pieId + "'";
		List<Map<String, Object>> dosageList = lineJdbcTemp.queryForList(querySql);
		if (dosageList == null || dosageList.isEmpty()) {
			return null;
		}
		//	查询发货单的标号
		ProductionInvoiceVo invoiceVo = invoiceDao.queryOverview(erpDb, invoiceId);
		Long strengthId = invoiceVo.getStrengthId();
		//	转换数据
		String batchTime = "";
		if (batTime != null) {
			batchTime = DateUtil.convertString(batTime);
		}
		//	真实消耗
		List<LabExpend> expendRList = new ArrayList<>();
		//	b库消耗
		List<LabExpendB> expendBList = new ArrayList<>();
		//	查询系数的sql
		String queryRateSql = "SELECT value from lab_level_material_log where storage_id = ? and line_id = ? and strength_id = ? and create_time <= ? ORDER BY create_time DESC LIMIT 1";
		for (int i = 0, s = dosageList.size(); i < s; i++) {
			Map<String, Object> dosage = dosageList.get(i);
			//	工控机的记录号
			String conExpendId = String.valueOf(dosage.get("ID"));
			//	工控机的料仓信息,根据料仓信息查询出当前消耗的材料
			String storage = String.valueOf(dosage.get("SiloName"));
			//	工控机的原料
			String bcsMaterial = String.valueOf(dosage.get("StuffName"));
			//	erp的原料id
			Long erpMaterialId = null;
			//	工控机的仓位id
			Long erpStorageId = null;
			SysStorageLog takeTimeOrStorage = sysStorageLogDao.findTakeTimeOrStorage(lineId, bcsMaterial, 1, batchTime);
			if (takeTimeOrStorage != null) {
				String erpMaterial = takeTimeOrStorage.getMaterial();
				erpMaterialId = takeTimeOrStorage.getMaterialId();
				erpStorageId = takeTimeOrStorage.getStorageId();
			}
			//	工控机的配方值
			Double recAmnt = Double.valueOf(String.valueOf(dosage.get("FormulaNum")));
			//	工控机的设定值
			Double planAmnt = Double.valueOf(String.valueOf(dosage.get("TargetNum")));
			//	工控机的实际值
			Double factAmnt = Double.valueOf(String.valueOf(dosage.get("StuffUsedNum")));
			//	工控机的含水率
			Double watFull = Double.valueOf(String.valueOf(dosage.get("WaterRate")));
			LabExpendB expendB = new LabExpendB();
			expendB.setInvoiceId(invoiceId);
			expendB.setLineId(lineId);
			expendB.setMaterialId(erpMaterialId);
			expendB.setStorageId(erpStorageId);
			expendB.setControlStorage(storage);
			expendB.setControlMaterial(bcsMaterial);
			expendB.setBatchId(batchId);
			expendB.setControlSetQuantity(planAmnt);
			expendB.setControlRealQuantity(factAmnt);
			expendB.setControlWater(watFull);
			expendB.setCreator(bcsCreater);
			expendB.setCreateTime(createDate);
			expendB.setUseTime(batTime);
			expendB.setConExpendId(conExpendId);
			expendBList.add(expendB);
			//	反推真实数据
			//	查询这个时间点的材料系数
			Double rate = 1d;
			Object[] rateParam = {erpStorageId, lineId, strengthId, batchTime};
			List<Map<String, Object>> rateList = mysqlJdbcTemplate.queryForList(queryRateSql, rateParam);
			if (rateList != null && rateList.size() > 0) {
				Map<String, Object> rateMap = rateList.get(0);
				if (rateMap != null) {
					Object valueObj = rateMap.get("value");
					if (valueObj != null) {
						rate = Double.valueOf(String.valueOf(valueObj));
					}
				}
			}
			//	反推真实值
			Double planAmntR = MathUtils.multiply(planAmnt, rate);
			Double factAmntR = MathUtils.multiply(factAmnt, rate);

			LabExpend labExpendR = new LabExpend();
			labExpendR.setInvoiceId(invoiceId);
			labExpendR.setLineId(lineId);
			labExpendR.setMaterialId(erpMaterialId);
			labExpendR.setStorageId(erpStorageId);
			labExpendR.setControlStorage(storage);
			labExpendR.setControlMaterial(bcsMaterial);
			labExpendR.setBatchId(batchId);
			labExpendR.setFormulaId(formulaId);
			labExpendR.setFormulaQuantity(recAmnt);
			labExpendR.setFormulaWater(formulaWater);
			labExpendR.setControlSetQuantity(planAmntR);
			labExpendR.setControlRealQuantity(factAmntR);
			labExpendR.setControlWater(watFull);
			labExpendR.setCreator(bcsCreater);
			labExpendR.setCreateTime(createDate);
			labExpendR.setUseTime(batTime);
			labExpendR.setConExpendId(conExpendId);
			expendRList.add(labExpendR);
		}
		//	存入b库数据
		labExpendBDao.saveBatch(expendBList);
		return expendRList;
	}

	@Override
	public List<ControlExpend> findWorkByPieId(Long lineId, Long batchId, String prodId, String pieId, Date batTime, Date createDate) {
		if (lineId == null || StringUtils.isBlank(pieId)) {
			return null;
		}
		SysLine line = getLine(lineId);
		if (line == null) {
			return null;
		}
		JdbcTemplate lineJdbcTemp = getLineJdbcTemp(line);
		//	查询sql
		//	查询sql
		String querySql = "SELECT  ID,HTID,TrayNum,StuffID,StuffName,SiloID\n" +
			"      ,SiloName,TargetNum,FormulaNum,StuffUsedNum,QueryNum,FallNum,WaterRate,SandRate,CheckNum\n" +
			"  FROM HistoryItems where HTID = '" + pieId + "'";
		List<Map<String, Object>> dosageList = lineJdbcTemp.queryForList(querySql);
		if (dosageList == null || dosageList.isEmpty()) {
			return null;
		}
		List<ControlExpend> expendList = new ArrayList<>();
		for (int i = 0, s = dosageList.size(); i < s; i++) {
			Map<String, Object> dosage = dosageList.get(i);
			//	工控机的记录号
			String conExpendId = String.valueOf(dosage.get("ID"));
			//	工控机的料仓信息,根据料仓信息查询出当前消耗的材料
			String storage = String.valueOf(dosage.get("SiloName"));
			//	工控机的原料
			String bcsMaterial = String.valueOf(dosage.get("StuffName"));
			String batchTime = "";
			if (batTime != null) {
				batchTime = DateUtil.convertString(batTime);
			}
			Long erpMaterialId = null;
			Long erpStorageId = null;
			SysStorageLog takeTimeOrStorage = sysStorageLogDao.findTakeTimeOrStorage(lineId, bcsMaterial, 1, batchTime);
			if (takeTimeOrStorage != null) {
				String erpMaterial = takeTimeOrStorage.getMaterial();
				erpMaterialId = takeTimeOrStorage.getMaterialId();
				erpStorageId = takeTimeOrStorage.getStorageId();
			}
			//	工控机的配方值
			Double recAmnt = Double.valueOf(String.valueOf(dosage.get("FormulaNum")));
			//	工控机的设定值
			Double planAmnt = Double.valueOf(String.valueOf(dosage.get("TargetNum")));
			//	工控机的实际值
			Double factAmnt = Double.valueOf(String.valueOf(dosage.get("StuffUsedNum")));
			//	工控机的含水率
			Double watFull = Double.valueOf(String.valueOf(dosage.get("WaterRate")));
			ControlExpend expend = new ControlExpend();
			expend.setLineId(lineId);
			expend.setErpBatchId(batchId);
			expend.setStorage(storage);
			expend.setMaterial(bcsMaterial);
			expend.setErpMaterialId(erpMaterialId);
			expend.setErpStorageId(erpStorageId);
			expend.setFormulaQuantity(recAmnt);
			expend.setControlSetQuantity(planAmnt);
			expend.setControlRealQuantity(factAmnt);
			expend.setControlWater(watFull);
			expend.setUseTime(batTime);
			expend.setStatus(StateEnum.ENABLED.getCode());
			expend.setCreator(bcsCreater);
			expend.setCreateTime(createDate);
			expend.setConExpendNo(conExpendId);
			expendList.add(expend);
		}
		return expendList;
	}

	@Override
	public List<LabExpendOther> findAll(Long lineId) {
		return null;
	}

	@Override
	public LabExpend queryByDosId(Long lineId, Long batchId, String dosId) {
		if (lineId == null || StringUtils.isBlank(dosId)) {
			return null;
		}
		SysLine line = getLine(lineId);
		if (line == null) {
			return null;
		}
		JdbcTemplate lineJdbcTemp = getLineJdbcTemp(line);
		if (lineJdbcTemp == null) {
			return null;
		}
		//	查询sql
		String querySql = "select SiloName controlStorage,StuffName controlMaterial,FormulaNum formulaQuantity,TargetNum controlSetQuantity,StuffUsedNum controlRealQuantity,WaterRate controlWater from HistoryItems where id = ?";
		Object[] params = {dosId};
		List<LabExpend> labExpends = lineJdbcTemp.query(querySql, params, BeanPropertyRowMapper.newInstance(LabExpend.class));
		if (labExpends == null || labExpends.isEmpty()) {
			return null;
		}
		LabExpend labExpend = labExpends.get(0);
		if (labExpend == null) {
			return null;
		}
		return labExpend;
	}

	@Override
	public List<Long> writeBackB(Long lineId, List<LabExpendVoB> labExpends) {
		return null;
	}

}
